package dao

import (
	"context"
	"core/models/db"
	"core/repo"
	"fmt"
	"framework/msError"
)

type TypeProgrammeDao struct {
	repo    *repo.Manager
	baseDao *BaseDao
}

func (t *TypeProgrammeDao) GetTypeProgramme(ctx context.Context, typeID uint) *[]db.TypeProgrammeHasOneType {
	typeProgramme := new([]db.TypeProgrammeHasOneType)
	where := fmt.Sprintf("%s", "is_show=1 ")
	if typeID == 1 {
		where += fmt.Sprintf("%s", " AND type_id NOT IN (3,4)")
	} else if typeID == 2 {
		where += fmt.Sprintf("%s", " AND type_id NOT IN (2,4)")
	} else if typeID == 3 {
		where += fmt.Sprintf("%s", " AND type_id NOT IN (2,3)")
	} else if typeID == 4 {
		where += fmt.Sprintf("%s", " AND type_id NOT IN (2,3,4)")
	}
	t.repo.DB.Client.WithContext(ctx).Model(&db.TypeProgramme{}).Where(where).Group("type_id").
		Preload("TypeInfo").
		Preload("SynthesisScheme").
		Preload("SynthesisScheme.ProgrammeSource").
		Preload("SynthesisScheme.ProgrammeSource.TypeInfo").
		Order("type_id").Find(typeProgramme)
	return typeProgramme
}

// UserWarehouseStarshipMj 获取用的母舰
func (t *TypeProgrammeDao) UserWarehouseStarshipMj(ctx context.Context, uid uint) uint {
	//var TypeID uint
	//t.repo.DB.Client.WithContext(ctx).Model(&db.WarehouseStarship{}).Where("is_mj=1 and uid=?", uid).Select("type_id").Scan(&TypeID)
	//return TypeID
	return 0
}

func (t *TypeProgrammeDao) FindTypeProgramme(ctx context.Context, sid uint) *db.TypeProgrammeHasOneTypeFind {
	data := new(db.TypeProgrammeHasOneTypeFind)
	t.repo.DB.Client.WithContext(ctx).Model(&db.TypeProgramme{}).Preload("TypeInfo").Preload("ProgrammeSource").
		Preload("ProgrammeSource.TypeInfo").Where("id=?", sid).First(data)
	return data
}

func (t *TypeProgrammeDao) Synthesis(ctx context.Context, uid uint, data *db.TypeProgrammeHasOneTypeFind, tableLog string) *msError.Error {
	//_db := t.repo.DB.Client.WithContext(ctx)
	//tx := _db.Begin()
	//_mdb := t.repo.Mongo
	//mtx, _ := _mdb.Client.StartSession()
	//_ = mtx.StartTransaction()
	//defer mtx.EndSession(ctx)
	//var err error
	////1.扣除方案数量
	//err = tx.Model(db.TypeProgramme{}).Where("id=?", data.ID).Update("remain", gorm.Expr("remain-?", 1)).Error
	//if err != nil {
	//	return biz.SqlError
	//}
	//for _, v := range data.ProgrammeSource {
	//	if v.TypeInfo.Types == 1 {
	//		continue
	//	}
	//	//2.获取仓库材料是否足够
	//	material := new(db.WarehouseMaterialHasOneType)
	//	_db.Model(db.WarehouseMaterial{}).Where("uid=? AND type_id=?", uid, v.TypeID).Preload("Types").First(&material)
	//	if material == nil || material.Num < v.Num {
	//		logs.Error("[synthesis]用户%d Synth err:材料不足, 余量%d,需扣除%d req=%v", uid, material.Num, v.Num, v)
	//		tx.Rollback()
	//		_ = mtx.AbortTransaction(ctx)
	//		return biz.NotEnoughGold
	//	}
	//	//3.扣除仓库材料
	//	err = tx.Model(db.WarehouseMaterial{}).Where("id", material.ID).Update("num", gorm.Expr("num-?", v.Num)).Error
	//	if err != nil {
	//		logs.Error("[synthesis]用户%d Synth err:扣除材料失败 req=%v,dbErr=%v", uid, v, err)
	//		tx.Rollback()
	//		_ = mtx.AbortTransaction(ctx)
	//		return biz.SqlError
	//	}
	//	// TODO 4.添加材料日志
	//	materialLog := &entity.MaterialLog{
	//		UID:        uid,
	//		WID:        material.ID,
	//		TypeID:     material.TypeID,
	//		TypeName:   material.Types.Name,
	//		TypeImg:    material.Types.Img,
	//		TypeModule: material.Types.Module,
	//		//LinkID:     fmt.Sprintf("%d", resource.ID),
	//		LinkTable: fmt.Sprintf("m_%v", tableLog),
	//		Ago:       material.Num,
	//		Num:       -v.Num,
	//		After:     material.Num - v.Num,
	//		Remarks:   fmt.Sprintf("合成-%v", data.TypeInfo.Name),
	//		AddTime:   time.Now().Format(time.DateTime),
	//	}
	//	_, err = _mdb.Db.Collection("material_log").InsertOne(ctx, materialLog)
	//	if err != nil {
	//		logs.Error("[synthesis]用户%d Synth err:添加材料变更失败 req=%v,dbErr=%v", uid, materialLog, err)
	//		tx.Rollback()
	//		_ = mtx.AbortTransaction(ctx)
	//		return biz.SqlError
	//	}
	//}
	//var wid uint
	//switch data.TypeInfo.Type {
	//case 1: //舰船
	//	ship := new(db.WarehouseStarship)
	//	if data.TypeInfo.Types == 1 {
	//		_db.Model(ship).Where("uid", uid).First(ship)
	//		wid = ship.ID
	//		if ship == nil || ship.ID == 0 {
	//			logs.Error("[synthesis]用户%d Synth err:获取舰船失败 req=%v,dbErr=%v", uid, ship, err)
	//			tx.Rollback()
	//			_ = mtx.AbortTransaction(ctx)
	//			return biz.RequestDataError
	//		}
	//		//5.修改母舰数据
	//		err = tx.Model(ship).Where("id=?", ship.ID).Update("type_id", data.TypeID).Error
	//		if err != nil {
	//			logs.Error("[synthesis]用户%d Synth err:修改数据失败 req=%v,dbErr=%v", uid, ship, err)
	//			tx.Rollback()
	//			_ = mtx.AbortTransaction(ctx)
	//			return biz.SqlError
	//		}
	//	} else {
	//		energyNum := utils.Random(1, 2)
	//		if data.TypeInfo.Types == 4 {
	//			energyNum = 3
	//		}
	//		//5.添加舰船数据
	//		ship = &db.WarehouseStarship{
	//			UID:       uid,
	//			TypeID:    data.TypeID,
	//			EnergyNum: int(energyNum),
	//		}
	//		err = tx.Model(ship).Create(ship).Error
	//		if err != nil {
	//			logs.Error("[synthesis]用户%d Synth err:添加舰船失败 req=%v,dbErr=%v", uid, ship, err)
	//			tx.Rollback()
	//			_ = mtx.AbortTransaction(ctx)
	//			return biz.SqlError
	//		}
	//		wid = ship.ID
	//		// TODO NFT添加一个tokenID
	//		widLen := len(fmt.Sprintf("%d", wid))
	//		var widStr string
	//		if widLen < 8 {
	//			for i := 0; i < 8-widLen; i++ {
	//				widStr += "0"
	//			}
	//		}
	//		widStr += fmt.Sprintf("%d", wid)
	//		tokenID := fmt.Sprintf("S%d%v", data.TypeInfo.Type, widStr)
	//		ship.TokenID = &tokenID
	//		err = tx.Save(ship).Error
	//		if err != nil {
	//			logs.Error("[synthesis]用户%d Synth err:修改舰船失败 req=%v,dbErr=%v", uid, ship, err)
	//			tx.Rollback()
	//			_ = mtx.AbortTransaction(ctx)
	//			return biz.SqlError
	//		}
	//	}
	//case 2: //港口
	//	build := &db.WarehouseBuild{
	//		UID:    uid,
	//		TypeID: data.TypeID,
	//	}
	//	//5.添加港口数据
	//	err = tx.Model(build).Create(build).Error
	//	if err != nil {
	//		logs.Error("[synthesis]用户%d Synth err:添加港口数据失败 req=%v,dbErr=%v", uid, build, err)
	//		tx.Rollback()
	//		_ = mtx.AbortTransaction(ctx)
	//		return biz.SqlError
	//	}
	//	wid = build.ID
	//	// TODO NFT添加一个tokenID
	//	widLen := len(fmt.Sprintf("%d", wid))
	//	var widStr string
	//	if widLen < 8 {
	//		for i := 0; i < 8-widLen; i++ {
	//			widStr += "0"
	//		}
	//	}
	//	widStr += fmt.Sprintf("%d", wid)
	//	tokenID := fmt.Sprintf("S%d%v", data.TypeInfo.Type, widStr)
	//	build.TokenID = &tokenID
	//	err = tx.Save(build).Error
	//	if err != nil {
	//		logs.Error("[synthesis]用户%d Synth err:修改舰船失败 req=%v,dbErr=%v", uid, build, err)
	//		tx.Rollback()
	//		_ = mtx.AbortTransaction(ctx)
	//		return biz.SqlError
	//	}
	//}
	////6.添加合成记录数据
	//log := &entity.SynthesisLog{
	//	WID:        wid,
	//	UID:        uid,
	//	TypeID:     data.TypeID,
	//	TypeName:   data.TypeInfo.Name,
	//	TypeImg:    data.TypeInfo.Img,
	//	TypeModule: data.TypeInfo.Module,
	//	Types:      data.TypeInfo.Types,
	//	AddTime:    time.Now().Format(time.DateTime),
	//}
	//_, err = _mdb.Db.Collection("synthesis_log").InsertOne(ctx, log)
	//if err != nil {
	//	logs.Error("[synthesis]用户%d Synth err:添加合成记录数据失败 req=%v,dbErr=%v", uid, log, err)
	//	tx.Rollback()
	//	_ = mtx.AbortTransaction(ctx)
	//	return biz.SqlError
	//}
	//_ = mtx.CommitTransaction(ctx)
	//tx.Commit()
	//
	//// TODO 上链
	//if wid != 0 && data.TypeInfo.Types != 1 {
	//	go t.baseDao.TimingObtainHax(uid, wid, data.TypeInfo.Type)
	//}
	return nil
}
func NewTypeProgrammeDao(m *repo.Manager) *TypeProgrammeDao {
	return &TypeProgrammeDao{
		repo:    m,
		baseDao: NewBaseDao(m),
	}
}
